/**
 * channelNameDb.ts
 * 负责使用 IndexedDB 持久化存储用户自定义的通道（监测点）名称。
 * 数据库结构:
 * - 数据库名: 'ChannelSettings'
 * - 对象存储空间 (表): 'ChannelNames'
 * - 主键: 'id' (格式: 'gatewayId-moduleId')
 * - 索引: 无
 * - 数据格式: { id: '1-101', name: '主变压器A相' }
 */

const DB_NAME = 'ChannelSettings';
const STORE_NAME = 'ChannelNames';
const DB_VERSION = 1;

class ChannelNameDb {
  private db: IDBDatabase | null = null;

  constructor() {
    this.initDb();
  }

  /**
   * 初始化数据库连接。
   * 如果数据库或对象存储空间不存在，则创建它们。
   */
  private initDb(): Promise<void> {
    return new Promise((resolve, reject) => {
      if (this.db) {
        resolve();
        return;
      }

      const request = indexedDB.open(DB_NAME, DB_VERSION);

      request.onerror = () => {
        console.error('IndexedDB 数据库打开失败');
        reject(request.error);
      };

      request.onsuccess = (event) => {
        this.db = (event.target as IDBOpenDBRequest).result;
        console.log('IndexedDB 数据库打开成功');
        resolve();
      };

      request.onupgradeneeded = (event) => {
        const db = (event.target as IDBOpenDBRequest).result;
        if (!db.objectStoreNames.contains(STORE_NAME)) {
          db.createObjectStore(STORE_NAME, { keyPath: 'id' });
          console.log(`对象存储空间 '${STORE_NAME}' 创建成功。`);
        }
      };
    });
  }

  /**
   * 确保数据库已连接。
   */
  private async ensureDb(): Promise<IDBDatabase> {
    if (!this.db) {
      await this.initDb();
    }
    if (!this.db) {
      throw new Error('数据库连接不可用');
    }
    return this.db;
  }

  /**
   * 获取所有已保存的自定义通道名称。
   * @returns 返回一个 Map，键为 'gatewayId-moduleId'，值为自定义名称。
   */
  public async getAllNames(): Promise<Map<string, string>> {
    try {
      const db = await this.ensureDb();
      const transaction = db.transaction(STORE_NAME, 'readonly');
      const store = transaction.objectStore(STORE_NAME);
      const request = store.getAll();

      return new Promise((resolve, reject) => {
        request.onerror = () => {
          console.error('获取所有通道名称失败:', request.error);
          reject(request.error);
        };

        request.onsuccess = () => {
          const nameMap = new Map<string, string>();
          request.result.forEach((item: { id: string; name: string }) => {
            nameMap.set(item.id, item.name);
          });
          resolve(nameMap);
        };
      });
    } catch (error) {
      console.error('执行 getAllNames 时出错:', error);
      return new Map(); // 出错时返回空Map
    }
  }

  /**
   * 保存或更新一个通道的自定义名称。
   * @param gatewayIp - 网关IP地址
   * @param moduleId - 模块ID
   * @param name - 自定义名称
   */
  public async saveName(gatewayIp: string, moduleId: number, name: string): Promise<void> {
    try {
      const db = await this.ensureDb();
      const transaction = db.transaction(STORE_NAME, 'readwrite');
      const store = transaction.objectStore(STORE_NAME);
      const id = `${gatewayIp}-${moduleId}`;
      
      const request = store.put({ id, name });

      return new Promise((resolve, reject) => {
        request.onerror = () => {
          console.error(`保存名称失败 (ID: ${id}):`, request.error);
          reject(request.error);
        };
        request.onsuccess = () => {
          console.log(`成功保存名称 (ID: ${id}, Name: ${name})`);
          resolve();
        };
      });
    } catch (error) {
      console.error('执行 saveName 时出错:', error);
    }
  }
}

// 导出单例实例
export const channelNameDb = new ChannelNameDb();
